﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;
using System.Runtime.InteropServices;

using SuperMapLib;

namespace SDB2DM
{
    class DatasetNode : JPGISXML, IMainNode
    {
        private AxSuperMapLib.AxSuperWorkspace superWksp = null;
        private XmlNode objectNode = null;
        private string srcPath = string.Empty;
        private string destPath = string.Empty;

        public DatasetNode(AxSuperMapLib.AxSuperWorkspace superWksp, string srcPath, string destPath) : base()
        {
            this.superWksp = superWksp;
            this.srcPath = srcPath;
            this.destPath = destPath;
        }

        private void BuildXMLForCoordinate()
        {
            XmlNode rscscNode = null;
            XmlNode rsNameNode = null;
            XmlNode rsIdentifierNode = null;
            XmlNode rsIdenfifierCodeNode = null;

            for (int i = 1; i < 3; i++)
            {
                rscscNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.CRDT_RS_TAG, Utility.JPS_URI);
                rsNameNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.CRDT_RS_NAME_TAG, Utility.JPS_URI);
                rsIdentifierNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.CRDT_IDENTIFIER_TAG, Utility.JPS_URI);
                rsIdenfifierCodeNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.CRDT_IDENTIFIER_CODE_TAG, Utility.JPS_URI);

                (rscscNode as XmlElement).SetAttribute(Utility.CM_ATTRIBUTE_ID_TAG, Utility.CRDT_ID_PREFIX + "0" + i.ToString());
                rsIdenfifierCodeNode.InnerText = i == 1 ? Utility.CRDT_SPATIAL_RS_VALUE : Utility.CRDT_TIME_RS_VALUE;

                objectNode.AppendChild(rscscNode);
                rscscNode.AppendChild(rsNameNode);
                rsNameNode.AppendChild(rsIdentifierNode);
                rsIdentifierNode.AppendChild(rsIdenfifierCodeNode);
            }
        }

        private void BuildSpatialData()
        {
            Utility utl = null;
            soRecordset objRS = null;
            soDatasetVector objDSV = null;
            soGeoPoint objPoint = null;

            utl = new Utility(superWksp, srcPath);
            utl.InitializeSource();

            objDSV = (soDatasetVector)utl.objSource.Datasets[Utility.FEATURE_HOSPITAL];
            objRS = objDSV.Query("-1 < 0", true, null, "");

            if (!(objRS.IsBOF() && objRS.IsEOF()))
            {
                int currentRowNo = 0;
                if (!objRS.IsBOF())
                {
                    objRS.MoveFirst();
                }
                for (; !objRS.IsEOF(); objRS.MoveNext())
                {
                    objPoint = (soGeoPoint)objRS.GetGeometry();
                    BuildXMLForSpatialSchema(objPoint.x, objPoint.y, ++currentRowNo);
                }

                Marshal.ReleaseComObject(objPoint);
                objPoint = null;
            }

            Marshal.ReleaseComObject(objRS);
            objRS = null;
            Marshal.ReleaseComObject(objDSV);
            objDSV = null;

            utl.ReleaseMemory();
        }

        private void BuildXMLForSpatialSchema(double pointX, double pointY, int idx)
        {
            XmlNode pointNode = null;
            XmlNode pointPosNode = null;
            XmlNode directPosNode = null;
            XmlNode coordinateNode = null;
            XmlNode dimensionNode = null;
            //const int PRECISION = 3;

            pointNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.SPATIAL_POINT_TAG, Utility.JPS_URI);
            pointPosNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.SPATIAL_POINT_POSITION_TAG, Utility.JPS_URI);
            directPosNode = XMLDoc.CreateElement(Utility.CM_JPS_TAG, Utility.SPATIAL_DIRECT_POSITION_TAG, Utility.JPS_URI);
            coordinateNode = XMLDoc.CreateElement(Utility.SPATIAL_COORDINATE_TAG);
            dimensionNode = XMLDoc.CreateElement(Utility.SPATIAL_DIMENSION_TAG);

            (pointNode as XmlElement).SetAttribute(
                Utility.CM_ATTRIBUTE_ID_TAG, Utility.SPATIAL_ID_PREFIX_POINT + String.Format("{0, 0:D4}", idx));    //0:0000
            coordinateNode.InnerText = String.Format("{0, 0:F3} {1, 0:F3}", pointX, pointY);
            dimensionNode.InnerText = Utility.SPATIAL_DIMENSION_VALUE;

            objectNode.AppendChild(pointNode);
            pointNode.AppendChild(pointPosNode);
            pointPosNode.AppendChild(directPosNode);
            directPosNode.AppendChild(coordinateNode);
            directPosNode.AppendChild(dimensionNode);
        }

        private void BuildApplicationData()
        {
            XmlNamespaceManager nsmgrJPS = null;
            XmlNodeList nodeList = null;

            nsmgrJPS = new XmlNamespaceManager(XMLDoc.NameTable);
            nsmgrJPS.AddNamespace(Utility.CM_JPS_TAG, Utility.JPS_URI);

            nodeList = objectNode.SelectNodes(Utility.CM_JPS_TAG + ":" + Utility.SPATIAL_POINT_TAG, nsmgrJPS);

            int currentNodeNo = 0;
            foreach (XmlNode node in nodeList)
            {
                BuildXMLForAppSchema(node.Attributes[Utility.CM_ATTRIBUTE_ID_TAG].Value, ++currentNodeNo);
            }
        }

        private void BuildXMLForAppSchema(string idName, int idx)
        {
            XmlNode schoolNode = null;
            XmlNode visiNode = null;
            XmlNode posNode = null;

            schoolNode = XMLDoc.CreateElement(Utility.CM_DOMAIN_TAG, Utility.APP_HOSPITAL_TAG, Utility.CM_SCHEMA_URI);
            visiNode = XMLDoc.CreateElement(Utility.APP_VISIBILITY_TAG);
            posNode = XMLDoc.CreateElement(Utility.CM_DOMAIN_TAG, Utility.APP_POS_TAG, Utility.CM_SCHEMA_URI);

            (schoolNode as XmlElement).SetAttribute(
                Utility.CM_ATTRIBUTE_ID_TAG, Utility.APP_HOSPITAL_TAG + String.Format("{0, 0:D4}", idx));
            visiNode.InnerText = Utility.APP_VISIBILITY_VALUE;
            (posNode as XmlElement).SetAttribute(Utility.CM_ATTRIBUTE_IDREF_TAG, idName);

            objectNode.AppendChild(schoolNode);
            schoolNode.AppendChild(visiNode);
            schoolNode.AppendChild(posNode);
        }

        private void BuildXMLForSpatialRSDefine(XmlNode datasetNode)
        {
            XmlNode spatialRSNode = null;

            for (int i = 1; i < 3; i++)
            {
                spatialRSNode = XMLDoc.CreateElement(Utility.CM_DOMAIN_TAG, Utility.SPATIAL_REF_DEF_TAG, Utility.CM_SCHEMA_URI);
                (spatialRSNode as XmlElement).SetAttribute(Utility.CM_ATTRIBUTE_IDREF_TAG, Utility.CRDT_ID_PREFIX + "0" + i.ToString());
                datasetNode.AppendChild(spatialRSNode);
            }
        }

        #region IMainNode メンバ

        public void BuildDatasetNode()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void BuildPortrayalNode()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
